package com.byx.chatserver.service.impl;

import com.byx.chatserver.pojo.RedisKeyDto;
import com.byx.chatserver.service.IRedisService;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Objects;

/**
 * RedisServiceImpl
 * 封装对Redis的操作
 * @author Superb
 * @date 2021/3/22 21:46
 */
@Service
public class RedisServiceImpl implements IRedisService {

    @Resource
    private RedisTemplate<Serializable, Serializable> redisTemplate;

    @Override
    public void addData(RedisKeyDto redisKeyDto) {
        redisTemplate.execute((RedisCallback<Object>) redisConnection -> {
            redisConnection.set(
                    Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(redisKeyDto.getKey())),
                    Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(redisKeyDto.getValue()))
            );
            return null;
        });
    }

    @Override
    public void delete(RedisKeyDto redisKeyDto) {
        redisTemplate.execute((RedisCallback<Object>) redisConnection -> {
            redisConnection.del(redisTemplate.getStringSerializer().serialize(redisKeyDto.getKey()));
            return null;
        });
    }

    @Override
    public RedisKeyDto redisGet(RedisKeyDto redisKeyDto) {
        return redisTemplate.execute(new RedisCallback<RedisKeyDto>() {
            @Override
            public RedisKeyDto doInRedis(RedisConnection redisConnection) throws DataAccessException {
                byte[] key = redisTemplate.getStringSerializer().serialize(redisKeyDto.getKey());
                if(key != null && Boolean.TRUE.equals(redisConnection.exists(key))){
                    byte[] value = redisConnection.get(key);
                    //从redis中取出的需要反序列化--- deserialize
                    String redisValue=redisTemplate.getStringSerializer().deserialize(value);
                    RedisKeyDto re=new RedisKeyDto();
                    re.setKey(redisKeyDto.getKey());
                    re.setValue(redisValue);
                    return re;
                }
                return null;
            }
        });
    }

    @Override
    public void addRedisData(RedisKeyDto redisKeyDto, int outTime) {
        redisTemplate.execute((RedisCallback<Object>) redisConnection -> {
            redisConnection.set(
                    Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(redisKeyDto.getKey())),
                    Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(redisKeyDto.getValue()))
            );
            redisConnection.expire(
                    Objects.requireNonNull(redisTemplate.getStringSerializer().serialize(redisKeyDto.getKey()))
                    ,outTime
            );
            return null;
        });
    }
}
